package com.yuzhi.master.sewage.rmstSz.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuzhi.common.core.page.PageDataInfo;
import com.yuzhi.common.util.DateUtils;
import com.yuzhi.master.drainCorrelation.domain.vo.DrainCorrelationVo;
import com.yuzhi.master.drainCorrelation.service.IDrainCorrelationService;
import com.yuzhi.master.drainRRmst.domain.vo.DrainRRmstVo;
import com.yuzhi.master.drainStPptnr.service.DrainStPptnrService;
import com.yuzhi.master.portableDevice.domain.bo.DrainRmstSzBo;
import com.yuzhi.master.sewage.rmstSz.entity.request.DrainRmstSzReq;
import com.yuzhi.master.sewage.rmstSz.entity.request.DrainRmstSzStatisticsReq;
import com.yuzhi.master.sewage.rmstSz.service.IAlarmRuleProcessor;
import org.apache.commons.lang3.StringUtils;
import com.yuzhi.master.sewage.rmstSz.entity.DrainRmstSz;
import com.yuzhi.master.sewage.rmstSz.entity.vo.*;
import com.yuzhi.master.sewage.rmstSz.mapper.DrainRmstSzMapper;
import com.yuzhi.master.sewage.rmstSz.service.DrainRmstSzService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 站点水质因子实时数据表 服务实现类
 */
@Slf4j
@Service
public class DrainRmstSzServiceImpl extends ServiceImpl<DrainRmstSzMapper, DrainRmstSz> implements DrainRmstSzService {

    @Autowired
    private DrainRmstSzMapper drainRmstSzMapper;

    @Autowired
    private DrainStPptnrService drainStPptnrService;

    @Autowired
    private IAlarmRuleProcessor alarmRuleProcessor;

    @Autowired
    private IDrainCorrelationService iDrainCorrelationService;

    @Override
    public List<DrainRmstSzWithStnmVo> getAllLatestWithStnm() {
        return drainRmstSzMapper.selectLatestAllWithStnm();
    }

    //污水处理厂实时数据检测
    @Override
    public List<MonitoringVo> getDailySewageReportDay(String factName) {
        return drainRmstSzMapper.getDailySewageReportDay(factName);
    }
    //污水处理厂实时数据检测
    @Override
    public List<MonitoringVo> getDailySewageReportMonth(String factName) {
        return drainRmstSzMapper.getDailySewageReportMonth(factName);
    }
    //污水处理厂实时数据检测
    @Override
    public List<MonitoringVo> getDailySewageReportYear(String factName) {
        return drainRmstSzMapper.getDailySewageReportYear(factName);
    }

    @Override
    public List<DrainRmstSzVo> getDailyMaxValues(String factId) {
        return drainRmstSzMapper.selectDailyMaxValues(factId);
    }

    @Override
    public List<MonitoringVo> getAvgData(String factId, int timeType) {
        return drainRmstSzMapper.getAvgData(factId, timeType);
    }

    @Override
    public List<PumpDataDTO> getLatestPumpStationData() {
        return drainRmstSzMapper.selectLatestPumpStationData();
    }

    @Override
    public List<MonitoringVo> getRealtimeData(String factName, LocalDateTime startTime, LocalDateTime endTime) {
        return drainRmstSzMapper.selectRealtimeData(factName, startTime, endTime);
    }

    /**
     * 查询首页测试设备实时数据
     * 每天最后一条
     * @param irrd 污水厂ID，为空时查询全部
     * @return
     */
    @Override
    public List<DrainRmstSzViewVo> getDrainRmstSzLastData(String irrd){
        List<DrainRmstSzViewVo> drainRmstSzViewVos = drainRmstSzMapper.getDrainRmstSzLastData(irrd);
        if(drainRmstSzViewVos!=null && !drainRmstSzViewVos.isEmpty())
        {
            drainRmstSzViewVos.forEach(vo -> vo.setStnm(vo.getShortName()));
        }
        return drainRmstSzViewVos;
    }

    // 允许查询的安全字段列表
    private static final Set<String> ALLOWED_FIELDS = Set.of(
            "qc_yw", "js_shs_ls", "flow_in_js", "cod_js", "ad_js", "js_sw", ""
    );
    public List<Map<String, Object>> getFieldData(String field,String irrdCode, String startTimeStr, String endTimeStr) {
        // 校验字段合法性（空字符串也允许）
        if (field != null && !ALLOWED_FIELDS.contains(field)) {
            throw new IllegalArgumentException("无效的查询字段: " + field);
        }

        Date startTime  = null;
        Date endTime  = null;
        if(StringUtils.isNotBlank(startTimeStr) && StringUtils.isNotBlank(endTimeStr))
        {
            startTime  = DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",startTimeStr+" 00:00:00");
            endTime  = DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",endTimeStr+" 23:59:59");

        }

        // 调用Mapper查询
        List<Map<String, Object>> result = drainRmstSzMapper.selectFieldData(field,irrdCode, startTime, endTime);

        // 统一字段名称（仅当查询单字段时）
        if (field != null && !field.isEmpty()) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return result.stream()
                    .map(row -> {
                        Map<String, Object> newRow = new HashMap<>();
                        Object cjTimeObj = row.get("cj_time");
                        String cjTimeStr = null;
                        if (cjTimeObj instanceof java.time.LocalDateTime) {
                            cjTimeStr = ((java.time.LocalDateTime) cjTimeObj).format(formatter);
                        } else if (cjTimeObj instanceof java.sql.Timestamp) {
                            cjTimeStr = ((java.sql.Timestamp) cjTimeObj).toLocalDateTime().format(formatter);
                        } else if (cjTimeObj instanceof java.util.Date) {
                            cjTimeStr = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((java.util.Date) cjTimeObj);
                        } else if (cjTimeObj != null) {
                            cjTimeStr = cjTimeObj.toString();
                        }
                        newRow.put("cj_time", cjTimeStr);
                        newRow.put("field_value", row.get("field_value"));
                        return newRow;
                    })
                    .collect(Collectors.toList());
        }
        return result;
    }

    /**
     * 查询污水处理厂监测数据
     *
     * @ factName  污水处理厂名称
     * @ startTime 监测开始时间
     * @ endTime   监测结束时间
     * @return 监测数据列表
     */
    public List<MonitoringVo> getTreatmentData(MonitoringVo monitoringVo) {
        return drainRmstSzMapper.selectSewageTreatmentData(monitoringVo);
    }

    @Override
    public List<PumpDataDTO> queryPumpData(PumpDataDTO dto) {
        return drainRmstSzMapper.queryPumpData(dto);
    }

    @Override
    public Map<String, Object> getDeviceStatusSummary() {
        return drainRmstSzMapper.getDeviceStatusSummary();
    }

    @Override
    //测站流量数据
    public void install(String msg, DrainRRmstVo drainRRmstVo) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(msg);
            JSONObject payload = jsonObject.getJSONObject("payload");
            
            // 当payload不存在时直接返回
            if (payload == null) {
                log.warn("payload不存在，跳过处理");
                return;
            }
            String factId = jsonObject.getString("deviceId");
            String QcYw = payload.getString("water_level");
            List<Map<String, Object>> manholeAltGrd = PipeManholeAltGrd(factId, QcYw);
            DrainRmstSz drainRmstSz = new DrainRmstSz();
            drainRmstSz.setFactId(jsonObject.getString("deviceId"));
            drainRmstSz.setIrrdRRmstCode(jsonObject.getString("deviceId"));
            drainRmstSz.setFactType(6);
            drainRmstSz.setFlowInJs(payload.getString("flow_in"));  //瞬时流量
            drainRmstSz.setJsLg(parseBigDecimal(payload.getString("flow_total")));  //累计流量
            drainRmstSz.setJsShsLs(payload.getString("flow_vel"));  //流速
            drainRmstSz.setQcYw(payload.getString("water_level"));    //水位
            // 设置满管液位，取第一个计算结果的liquid_level值
            if (manholeAltGrd != null && !manholeAltGrd.isEmpty()) {
                Map<String, Object> first = manholeAltGrd.get(0);
                Object liquidLevelObj = first.get("liquid_level");
                if (liquidLevelObj != null) {
                    BigDecimal lv = new BigDecimal(liquidLevelObj.toString()).setScale(3, java.math.RoundingMode.HALF_UP);
                    drainRmstSz.setLiquidLevel(lv);
                }
                Object fullLevelPercentObj = first.get("full_level_percent");
                if (fullLevelPercentObj != null) {
                    BigDecimal flp = new BigDecimal(fullLevelPercentObj.toString()).setScale(3, java.math.RoundingMode.HALF_UP);
                    drainRmstSz.setFullLevel(flp);
                }
            }
            drainRmstSz.setJsSw(parseBigDecimal(payload.getString("temp")));    //温度
            drainRmstSz.setBatPow(parseBigDecimal(payload.getString("voltage")));    //电源电压
            String timeStr = payload.getString("time");
            // 格式化输出
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime tm = LocalDateTime.parse(timeStr, formatter);
            drainRmstSz.setCjTime(tm);
            drainRmstSz.setXtTime(tm);
            // 检查报警规则（异常时设置alert为true，正常为false）
            List<String> alarmMessages = alarmRuleProcessor.checkAlarmRules(drainRmstSz,drainRRmstVo);
            if (alarmMessages != null && !alarmMessages.isEmpty()) {
                drainRmstSz.setAlert(true);
                for (String m : alarmMessages) {
                    log.warn("报警触发: {}", m);
                }
            }
            drainRmstSzMapper.insert(drainRmstSz);

        }catch (Exception e) {
            log.error("保存消息到表失败", e);
        }

    }

    @Override
    //测站水质数据
    public void saveSz(String msg, DrainRRmstVo drainRRmstVo) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(msg);
            JSONObject payload = jsonObject.getJSONObject("payload");
            // 当payload不存在时直接返回
            if (payload == null) {
                log.warn("payload不存在，跳过处理");
                return;
            }
            String factId = jsonObject.getString("deviceId");
            String QcYw = payload.getString("water_level");
            List<Map<String, Object>> manholeAltGrd = PipeManholeAltGrd(factId, QcYw);
            DrainRmstSz drainRmstSz = new DrainRmstSz();
            drainRmstSz.setFactId(factId);
            drainRmstSz.setIrrdRRmstCode(factId);
            drainRmstSz.setFactType(5);
            drainRmstSz.setFlowInJs(payload.getString("flow_in"));  //瞬时流量
            drainRmstSz.setJsLg(parseBigDecimal(payload.getString("flow_total")));  //累计流量
            drainRmstSz.setJsShsLs(payload.getString("flow_vel"));  //流速
            drainRmstSz.setQcYw(QcYw);    //水位
            drainRmstSz.setCodJs(parseBigDecimal(payload.getString("COD")));    //COD
            drainRmstSz.setAdJs(parseBigDecimal(payload.getString("NH3N")));   //氨氮
            drainRmstSz.setJsSw(parseBigDecimal(payload.getString("temp")));    //温度
            drainRmstSz.setBatPow(parseBigDecimal(payload.getString("voltage")));    //电源电压
            // 设置液位与充满度百分比，保留三位小数
            if (manholeAltGrd != null && !manholeAltGrd.isEmpty()) {
                Map<String, Object> first = manholeAltGrd.get(0);
                Object liquidLevelObj = first.get("liquid_level");
                if (liquidLevelObj != null) {
                    BigDecimal lv = new BigDecimal(liquidLevelObj.toString()).setScale(3, java.math.RoundingMode.HALF_UP);
                    drainRmstSz.setLiquidLevel(lv);
                }
                Object fullLevelPercentObj = first.get("full_level_percent");
                if (fullLevelPercentObj != null) {
                    BigDecimal flp = new BigDecimal(fullLevelPercentObj.toString()).setScale(3, java.math.RoundingMode.HALF_UP);
                    drainRmstSz.setFullLevel(flp);
                }
            }
            String timeStr = payload.getString("time");     //采集时间
            // 格式化输出
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime tm = LocalDateTime.parse(timeStr, formatter);
            drainRmstSz.setCjTime(tm);
            drainRmstSz.setXtTime(tm);
            List<String> alarmMessages = alarmRuleProcessor.checkAlarmRules(drainRmstSz,drainRRmstVo);
            if (alarmMessages != null && !alarmMessages.isEmpty()) {
                drainRmstSz.setAlert(true);
                for (String m : alarmMessages) {
                    log.warn("报警触发: {}", m);
                }
            }
            // 保存到数据库
            drainRmstSzMapper.insert(drainRmstSz);
        }catch (Exception e) {
            log.error("保存消息到表失败", e);
        }
    }




    private List<Map<String, Object>> PipeManholeAltGrd(String factId, String QcYw) {
        DrainCorrelationVo drainCorrelationVo = iDrainCorrelationService.queryByStcd(factId);
        List<Map<String, Object>> resultList = new ArrayList<>();
        
        if (drainCorrelationVo != null) {
            Map<String, Object> resultItem = new HashMap<>();
            
            // 安全地获取并转换数值，支持BigDecimal和String类型
            Double manholeAlt = getDoubleValue(drainCorrelationVo.getManholeAlt());
            Double draiPipePaltBeg = getDoubleValue(drainCorrelationVo.getDraiPipePaltBeg());
            Object draiPipeD1Obj = drainCorrelationVo.getDraiPipeD1();
            
            // 计算 LiquidLevel = manhole_alt - drai_pipe_palt_beg + QcYw
            try {
                if (manholeAlt != null && draiPipePaltBeg != null && QcYw != null && draiPipeD1Obj != null) {
                    double qcYw = Double.parseDouble(QcYw);
                    
                    // 计算液位高度
                    double liquidLevel = manholeAlt - draiPipePaltBeg + qcYw;
                    // 保留三位小数
                    liquidLevel = Math.round(liquidLevel * 1000.0) / 1000.0;
                    
                    // 计算充满度 full_level = liquidLevel / drai_pipe_d1
                    double draiPipeD1 = 0.0;
                    if (draiPipeD1Obj instanceof Integer) {
                        draiPipeD1 = ((Integer) draiPipeD1Obj).doubleValue();
                    } else if (draiPipeD1Obj instanceof Double) {
                        draiPipeD1 = (Double) draiPipeD1Obj;
                    } else if (draiPipeD1Obj instanceof String) {
                        draiPipeD1 = Double.parseDouble((String) draiPipeD1Obj);
                    } else if (draiPipeD1Obj instanceof BigDecimal) {
                        draiPipeD1 = ((BigDecimal) draiPipeD1Obj).doubleValue();
                    }
                    
                    double fullLevel = 0.0;
                    if (draiPipeD1 > 0) {
                        fullLevel = qcYw / (draiPipeD1 / 1000);
                    }
                    
                    // 转换为百分比 (乘以100)
                    double fullLevelPercent = fullLevel * 100;
                    
                    // 复制原始数据到结果
                    resultItem.put("id", drainCorrelationVo.getId());
                    resultItem.put("stcd", drainCorrelationVo.getStcd());
                    resultItem.put("draiPipeId", drainCorrelationVo.getDraiPipeId());
                    resultItem.put("manholeId", drainCorrelationVo.getManholeId());
                    resultItem.put("draiPumpId", drainCorrelationVo.getDraiPumpId());
                    resultItem.put("draiPipePaltBeg", drainCorrelationVo.getDraiPipePaltBeg());
                    resultItem.put("manholeAlt", drainCorrelationVo.getManholeAlt());
                    resultItem.put("draiPipeD1", drainCorrelationVo.getDraiPipeD1());
                    resultItem.put("trunkmainId", drainCorrelationVo.getTrunkmainId());
                    resultItem.put("rainfallId", drainCorrelationVo.getRainfallId());
                    
                    // 添加计算后的液位高度（保留三位小数）
                    resultItem.put("liquid_level", liquidLevel);
                    // 添加充满度（小数形式）
                    resultItem.put("full_level", fullLevel);
                    // 添加充满度百分比
                    resultItem.put("full_level_percent", fullLevelPercent);
                    
                    resultList.add(resultItem);
                    
                    // 记录计算日志
                    log.info("计算完成 - factId: {}, liquidLevel: {}, fullLevel: {}, fullLevelPercent: {}%", 
                            factId, liquidLevel, fullLevel, fullLevelPercent);
                    
                } else {
                    // 如果数据不完整，记录日志并跳过
                    log.warn("数据不完整，跳过计算。factId: {}, manhole_alt: {}, drai_pipe_palt_beg: {}, QcYw: {}, drai_pipe_d1: {}", 
                            factId, manholeAlt, draiPipePaltBeg, QcYw, draiPipeD1Obj);
                }
            } catch (NumberFormatException e) {
                log.error("数值转换异常，factId: {}, manhole_alt: {}, drai_pipe_palt_beg: {}, QcYw: {}, drai_pipe_d1: {}", 
                        factId, manholeAlt, draiPipePaltBeg, QcYw, draiPipeD1Obj, e);
            }
        } else {
            log.warn("未找到测站ID为 {} 的关联信息", factId);
        }
        
        return resultList;
    }

    /**
     * 安全地获取数值，支持BigDecimal、String、Integer、Double等类型
     * @param value 原始值
     * @return 转换后的Double值，如果转换失败返回null
     */
    private Double getDoubleValue(Object value) {
        if (value == null) {
            return null;
        }
        
        try {
            if (value instanceof BigDecimal) {
                return ((BigDecimal) value).doubleValue();
            } else if (value instanceof String) {
                return Double.parseDouble((String) value);
            } else if (value instanceof Integer) {
                return ((Integer) value).doubleValue();
            } else if (value instanceof Double) {
                return (Double) value;
            } else if (value instanceof Long) {
                return ((Long) value).doubleValue();
            } else if (value instanceof Float) {
                return ((Float) value).doubleValue();
            } else {
                // 尝试转换为字符串再解析
                return Double.parseDouble(value.toString());
            }
        } catch (NumberFormatException e) {
            log.warn("无法转换数值: {}, 类型: {}", value, value.getClass().getSimpleName());
            return null;
        }
    }

    /**
     * 静态测试方法，用于单元测试
     * @param factId 工厂ID
     * @param QcYw 水位值
     * @return 计算结果列表
     */
    public static List<Map<String, Object>> testPipeManholeAltGrd(String factId, String QcYw) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        
        // 模拟测试数据，用于测试计算逻辑
        Map<String, Object> testData = new HashMap<>();
        testData.put("fact_id", factId);
        testData.put("manhole_alt", "13.5");
        testData.put("drai_pipe_d1", 1000);
        testData.put("manhole_alt_grd", "105");
        testData.put("drai_pipe_palt_beg", "13.4");
        testData.put("well_id", "1002");
        
        try {
            if (QcYw != null) {
                double manholeAlt = Double.parseDouble((String) testData.get("manhole_alt"));
                double draiPipePaltBeg = Double.parseDouble((String) testData.get("drai_pipe_palt_beg"));
                double qcYw = Double.parseDouble(QcYw);
                double draiPipeD1 = (Integer) testData.get("drai_pipe_d1");
                
                // 计算液位高度
                double liquidLevel = manholeAlt - draiPipePaltBeg + qcYw;
                
                // 计算充满度
                double fullLevel = 0.0;
                if (draiPipeD1 > 0) {
                    fullLevel = qcYw / (draiPipeD1 / 1000.0);
                }

                
                // 转换为百分比
                double fullLevelPercent = fullLevel * 100;
                
                // 复制测试数据到结果
                resultList.add(testData);
                // 添加计算后的液位高度
                testData.put("Liquid_level", liquidLevel);
                // 添加充满度（小数形式）
                testData.put("full_level", fullLevel);
                // 添加充满度百分比
                testData.put("fullLevelPercent", fullLevelPercent);
            }
        } catch (NumberFormatException e) {
            System.err.println("数值转换异常: " + e.getMessage());
        }
        
        return resultList;
    }


    private void validEntityBeforeSave(DrainRmstSz add) {
    }

    /**
     * 安全转换字符串为BigDecimal，异常时返回0
     */
    private BigDecimal parseBigDecimal(String str) {
        try {
            return (str == null || str.isEmpty()) ? BigDecimal.ZERO : new BigDecimal(str);
        } catch (NumberFormatException e) {
            log.warn("BigDecimal转换异常，值：{}");
            return BigDecimal.ZERO;
        }
    }

    /**
     * 查询水质和流量的当天的最新数据
     * @param req
     * @return
     */
    @Override
    public List<DrainRmstSzVo>   getLatestWaterQualityAndFlow(DrainRmstSzReq req)
    {
        //查询类型(1:整点   2:实时)
        String queryType  =  req.getQueryType();

        LocalDate  cjTimeStrart  = null;
        LocalDate  cjTimeEnd =null;
        if(req.getCjTimeStrart()!=null && req.getCjTimeEnd()!=null)
        {
            cjTimeStrart  = req.getCjTimeStrart().toLocalDate();
            cjTimeEnd  = req.getCjTimeEnd().toLocalDate();
        }
        // 采集实时数据
        if("2".equals(queryType))
        {
            List<DrainRmstSzVo>  list  = drainRmstSzMapper.getLatestWaterQualityAndFlow(req.getRmstCodeList(),cjTimeStrart
                    ,cjTimeEnd,req.getFactype());

            return list;
        }
        else if("1".equals(queryType))
        {
            //  取整点的雨量
            List<Map<String, Object>>   yuList =  drainStPptnrService.getRainfallData(req);

            List<DrainRmstSzVo>  list  = drainRmstSzMapper.getHourWaterQualityAndFlow(req.getRmstCodeList(),cjTimeStrart
                    ,cjTimeEnd,req.getFactype());

            //将雨量的数据添加集合
            for(DrainRmstSzVo  szVo : list)
            {
                String irrdRRmstCode  = szVo.getIrrdRRmstCode();
                LocalDateTime cjTme = szVo.getCjTime();
                //根据测站编码和时间(年月日时)匹配取雨量
                BigDecimal drp = getDrpData( irrdRRmstCode, cjTme, yuList);
                if(drp.compareTo(BigDecimal.ZERO) != 0)
                {
                    String msg = String.format(">>>>>>>测站编码{%s},时间{%s}取得雨量{%s}>>>>>",irrdRRmstCode,cjTme.toString(),drp.toString());
                    log.info(msg);
                }
                szVo.setDrp(drp);

            }

            return  list;
        }


        return null;
    }


    /**
     * 根据测站编码和整点时间段取雨量
     * @return
     */
    private BigDecimal  getDrpData(String irrdRRmstCode,LocalDateTime cjTme,List<Map<String, Object>>   yuList)
    {

        for(Map<String, Object>  map  : yuList)
        {
            //测站编码
            String stcd  =  (String)map.get("originalStcd");
            //时间
            LocalDateTime  tm  = null;
            if(map.get("tm")!=null)
            {
                Timestamp timestamp = (Timestamp) map.get("tm");
                tm  = timestamp.toLocalDateTime();
            }
            // 取雨量
            BigDecimal drp  = (BigDecimal)map.get("drp");

            if(tm!=null && cjTme!=null)
            {
                //比较年月日时
                LocalDateTime truncatedDt1 = tm.truncatedTo(ChronoUnit.HOURS);
                LocalDateTime truncatedDt2 = cjTme.truncatedTo(ChronoUnit.HOURS);

                if(irrdRRmstCode.equals(stcd) && truncatedDt1.equals(truncatedDt2))
                {
                    return drp;
                }

            }

        }

        return BigDecimal.ZERO;
    }


    private LambdaQueryWrapper<DrainRmstSz> buildQueryWrapper(DrainRmstSzReq request) {
        LambdaQueryWrapper<DrainRmstSz> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(request.getFactId()), DrainRmstSz::getFactId, request.getFactId());
        lqw.eq(DrainRmstSz::getFactType,7);
        lqw.between(request.getCjTimeStrart() != null && request.getCjTimeEnd() != null,
                DrainRmstSz::getCjTime,request.getCjTimeStrart(),request.getCjTimeEnd());
        return lqw;
    }

    /**
     * 管网沿程分析
     * 取距离查询时间点最近的数据
     * @param req
     * @return
     */
    @Override
    public List<DrainRmstSzVo>   getPipeNetworkAnalysis(DrainRmstSzReq req)
    {
        //查询类型(1:整点   2:实时)
        String queryType  =  req.getQueryType();

        // 采集实时数据
        if("2".equals(queryType))
        {
            List<DrainRmstSzVo>  list  = drainRmstSzMapper.getRecentWaterQualityAndFlow(req.getRmstCodeList(),
                    req.getStartTime() , req.getFactype());

            return list;
        }
        else if("1".equals(queryType))
        {
            //  取整点的雨量
            List<Map<String, Object>>   yuList =  drainStPptnrService.getRainfallData(req);

            List<DrainRmstSzVo>  list  = drainRmstSzMapper.getRecentHourWaterQualityAndFlow(req.getRmstCodeList(),
                    req.getStartTime(),req.getFactype());

            //将雨量的数据添加集合
            for(DrainRmstSzVo  szVo : list)
            {
                String irrdRRmstCode  = szVo.getIrrdRRmstCode();
                LocalDateTime cjTme = szVo.getCjTime();
                //根据测站编码和时间(年月日时)匹配取雨量
                BigDecimal drp = getDrpData( irrdRRmstCode, cjTme, yuList);
                if(drp.compareTo(BigDecimal.ZERO) != 0)
                {
                    String msg = String.format(">>>>>>>测站编码{%s},时间{%s}取得雨量{%s}>>>>>",irrdRRmstCode,cjTme.toString(),drp.toString());
                    log.info(msg);
                }

                szVo.setDrp(drp);

            }
            return  list;
        }


        return null;

    }

    @Override
    public Boolean insertByBo(DrainRmstSzBo bo) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime cjTm = LocalDateTime.parse(bo.getCjTime(), formatter);
        LocalDateTime XtTm = LocalDateTime.parse(bo.getXtTime(), formatter);
        DrainRmstSz add = BeanUtil.toBean(bo, DrainRmstSz.class);
        add.setCjTime(cjTm);
        add.setXtTime(XtTm);
        add.setFactType(7);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setFactId(add.getFactId());
        }
        return flag;
    }

    @Override
    public List<Map<String, Object>> selectByRmstSzList() {
        return baseMapper.selectByRmstSzList();
    }

    @Override
    public Boolean updateByBo(DrainRmstSzBo bo) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime cjTm = LocalDateTime.parse(bo.getCjTime(), formatter);
        LocalDateTime XtTm = LocalDateTime.parse(bo.getXtTime(), formatter);
        DrainRmstSz update = BeanUtil.toBean(bo, DrainRmstSz.class);
        update.setCjTime(cjTm);
        update.setXtTime(XtTm);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public Boolean deleteById(String id, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteById(id) > 0;
    }

    /**
     * 查询污水厂当天最新的数据
     * @return
     */
    @Override
    public List<DrainRmstSzVo>   getLastMeetStatus()
    {
        return  baseMapper.getLastMeetStatus();
    }

    /**
     * 导出污水厂水质实时数据
     * @param request
     * @return
     */
    @Override
    public List<DrainRmstSzVo> selectFactoryList(DrainRmstSzReq request)
    {
        LocalDate cjTimeStrart  = null;
        LocalDate cjTimeEnd = null;
        if(request.getCjTimeStrart()!=null && request.getCjTimeEnd() != null)
        {
            cjTimeStrart = request.getCjTimeStrart().toLocalDate() ;
            cjTimeEnd = request.getCjTimeEnd().toLocalDate();

        }

        List<DrainRmstSzVo> voList  = baseMapper.selectFactoryList(cjTimeStrart,cjTimeEnd,request.getFactId());

        return voList;

    }


    /**
     * 管网监测列表(水质和流量)
     * @param request
     * @return
     */
    @Override
    public PageDataInfo<DrainRmstSzVo> listPipelineDataByPage(DrainRmstSzReq request)
    {
        QueryWrapper<DrainRmstSz> queryWrapper = new QueryWrapper<>();
        // 查询类型(1:整点   2:实时)
        String queryType  = request.getQueryType();
        if("1".equals(queryType))
        {
            queryWrapper.eq("rr.deleted",0);

            if(request.getCjTimeStrart()!=null && request.getCjTimeEnd() != null)
            {
                LocalDateTime  startTime = request.getCjTimeStrart().toLocalDate().atStartOfDay();
                LocalDateTime  endTime = request.getCjTimeEnd().toLocalDate().atTime(LocalTime.MAX);

                queryWrapper.between("sz.tm",startTime,endTime);
            }
            if(request.getRmstCodeList() != null && !request.getRmstCodeList().isEmpty())
            {
                queryWrapper.in("sz.stcd",request.getRmstCodeList());
            }

            Page<DrainRmstSzVo> result = baseMapper.listPipelineHourPage(request.getPageQuery().build(), queryWrapper);

            return PageDataInfo.build(result);
        }
        else   //实时数据
        {
            List<Integer>  factTypeList  = new ArrayList<>();
            factTypeList.add(5);  //水质
            factTypeList.add(6);  //流量

            queryWrapper.eq("rr.deleted",0);
            queryWrapper.in("sz.fact_type",factTypeList);

            if(request.getCjTimeStrart()!=null && request.getCjTimeEnd() != null)
            {
                LocalDateTime  startTime = request.getCjTimeStrart().toLocalDate().atStartOfDay();
                LocalDateTime  endTime = request.getCjTimeEnd().toLocalDate().atTime(LocalTime.MAX);

                queryWrapper.between("sz.cj_time",startTime,endTime);
            }
            if(request.getRmstCodeList() != null && !request.getRmstCodeList().isEmpty())
            {
                queryWrapper.in("sz.irrd_r_rmst_code",request.getRmstCodeList());
            }

            Page<DrainRmstSzVo> result = baseMapper.listPipelineRealPage(request.getPageQuery().build(), queryWrapper);

            return PageDataInfo.build(result);
        }

    }


    /**
     * 统计污水厂当日处理量
     * @return
     */
    @Override
    public Map<String, double[]>  statisticsRmstSzFactry()
    {
        LocalDate cjTimeStrart  =  LocalDate.now();
        LocalDate cjTimeEnd = LocalDate.now();

        //取污水厂当天的处理数据
        List<DrainRmstSzVo> voList  = baseMapper.selectFactoryList(cjTimeStrart,cjTimeEnd,null);

        // 取小时  24小时制
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH");
        voList.forEach(obj -> {
            // CjDate(LocalDateTime)转换为String并赋值给CjDateStr
            obj.setCjTimeStr(obj.getCjTime().format(formatter)+":00");
        });

        //按照日期统计数据
        Map<String, double[]> stats = voList.stream()
                .collect(Collectors.groupingBy(
                        DrainRmstSzVo::getCjTimeStr,
                        TreeMap::new, // 保持时间顺序
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                list -> {
                                    // 1. 计算 CsLg（直接求和）
                                    double estimated = list.stream()
                                            .map(u -> Optional.ofNullable(u.getCsLg()).orElse(BigDecimal.ZERO))
                                            .mapToDouble(BigDecimal::doubleValue)
                                            .sum();
                                    // 2.计算污水厂设计规模  FactCapDsn（按 factId(污水厂ID)去重后求和）
                                    double actual = list.stream()
                                            .collect(Collectors.toMap(
                                                    DrainRmstSzVo::getFactId,
                                                    u -> Optional.ofNullable(u.getFactCapDsn()).orElse(0.0),
                                                    (existing, replacement) -> existing // 去重：保留已存在的值
                                            ))
                                            .values()
                                            .stream()
                                            .mapToDouble(Double::doubleValue)
                                            .sum();
                                    return new double[]{estimated, actual};
                                }
                        )
                ));

        return stats;
    }

    /**
     * 根据条件查询js_lg数据
     * 支持以下查询模式：
     * 1. factId为空且时间范围为空：查询全部测站的最新一条js_lg值
     * 2. factId不为空且时间范围为空：根据factId查询测站的最新一条js_lg值
     * 3. factId和时间范围都不为空：查询指定测站在时间范围内每天最新一条数据的总和
     * 4. factId为空且时间范围不为空：查询每个测站在时间范围内每天最新一条数据的总和
     * @param request 查询请求参数
     * @return 查询结果（可能是最新记录列表或统计结果列表）
     */
    @Override
    public Object getJsLgDataByCondition(DrainRmstSzStatisticsReq request) {
        boolean hasFactId = StringUtils.isNotBlank(request.getFactId());
        boolean hasTimeRange = request.getStartTime() != null && request.getEndTime() != null;

        // 仅依据 factId 与时间范围判断
        if (!hasTimeRange) {
            // 无时间范围：查询最新一条记录，可选按factId过滤
            return baseMapper.selectLatestJsLgRecords(hasFactId ? request.getFactId() : null);
        }

        // 有时间范围：查询每天最后一条记录统计，可选按factId过滤
        return baseMapper.selectDailyLastJsLgStatistics(
                hasFactId ? request.getFactId() : null,
                request.getStartTime(),
                request.getEndTime()
        );

    }

    @Override
    public List<String> selectByRmstHour() {
        return baseMapper.selectByRmstHour();
    }

}
